package com.solo.game.snake;

import java.awt.Color;
import java.awt.Point;
import java.util.HashMap;

import javax.swing.JButton;

public class Game {

    // 游戏状态 初始
    public static final String GAME_STATE_INITIAL = "initial";

    // 游戏状态 进行
    public static final String GAME_STATE_RUNNING = "running";

    // 游戏状态 暂停
    public static final String GAME_STATE_SUSPEND = "suspend";

    // 游戏状态 停止
    public static final String GAME_STATE_STOP = "stop";

    // 战场标记 true表示可用，false表示不可用
    public boolean[][] fieldFlag;

    public HashMap<JButton, Point> map; // 节点和坐标的映射

    private JButton[][] matrix;

    // 游戏状态
    private String state;

    private int row;

    private int col;

    private Snake snake;
    
    private Bonus bonus;

    private String action;
    
    private Preference preference;
    
    private GameEngine gameEngine;

    public Game(JButton[][] matrix, Preference pref) {

        this.matrix = matrix;
        this.preference = pref;
        this.bonus = new Bonus(this);
        this.row = pref.getRow();
        this.col = pref.getColumn();
        this.fieldFlag = new boolean[row][col];
        this.map = new HashMap<JButton, Point>();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                map.put(this.matrix[i][j], new Point(i, j));
            }
        }
        this.state = Game.GAME_STATE_STOP;
    }
    
    /**
     * 
     * <P>描述: 判断该坐标是否可用
     * true表示可用
     * false表示不可用
     * 
     * @author Zangrong.Solo
     * 日期: Dec 19, 2012 9:12:01 AM
     * @param x
     * @param y
     * @return
     */
    public boolean isFieldAvailable(int x, int y)
    {
        return this.fieldFlag[x][y];
    }
    
    /**
     * 
     * <P>描述: 设置指定坐标是否可用
     * 
     * @author Zangrong.Solo
     * 日期: Dec 19, 2012 10:11:08 AM
     * @param x
     * @param y
     * @param flag
     */
    public void setFieldAvailable(int x, int y, boolean flag)
    {
        this.fieldFlag[x][y] = flag;
    }
    
    public void setFieldColor(int x, int y, Color color) {
        this.matrix[x][y].setBackground(color);

    }
    
    public void addHead(int x, int y)
    {
        this.snake.add(this.matrix[x][y]);
    }
    
    public Point getPoint(JButton btn)
    {
        return this.map.get(btn);
    }
    
    public Preference getPreference() {
        return this.preference;
    }

    /**
     * 
     * <P>
     * 描述: 初始化一局游戏
     * 
     * @author Zangrong.Solo 日期: Dec 18, 2012 5:33:23 PM
     */
    public void initGame() {

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                this.matrix[i][j].setBackground(this.preference.getGroundColor());
                fieldFlag[i][j] = true;
            }
        }
        initSnake();
        this.bonus.createBonus();
        this.action = Action.ACTION_KEY_UP;
        this.state = GAME_STATE_INITIAL;
        this.gameEngine = new GameEngine(this);
        Thread thread = new Thread(gameEngine);
        thread.start();
    }

    /**
     * 初始化蛇
     */
    private void initSnake() {
        // 蛇的初始位置默认在右下角起6，6，蛇身长6
        // 将来考虑随机和开始倒计时
        snake = new Snake(this);
        int snakeLength = this.preference.getSnakeLength();
        int r = this.row - snakeLength;
        int c = this.col - snakeLength;
        for (int i = row - 1; i >= r; i--) {
            // 设置节点颜色
            matrix[i][c].setBackground(this.preference.getSnakeColor());
            // 保存新增节点
            snake.add(matrix[i][c]);
            // 标记结点位置被占用
            fieldFlag[i][c] = false;
        }
        matrix[c][c].setBackground(this.preference.getSnakeHeadColor());
        snake.setHead(c, c);
    }

    
    public Snake getSnake() {
        return snake;
    }
    
    public String getAction() {
        return this.action;
    }
    
    /**
     * 
     * <P>
     * 描述: 开始游戏
     * 
     * @author Zangrong.Solo 日期: Dec 18, 2012 4:47:03 PM
     */
    public void startGame() {

    }

    /**
     * 
     * <P>
     * 描述: 设置游戏当前的动作
     * 
     * @author Zangrong.Solo 日期: Dec 18, 2012 5:12:11 PM
     * @param action
     */
    public void setAction(String action) {
        if (Action.ACTION_KEY_LEFT.equals(action)) {
            // 左必须是当前操作处于上或下时才可以设置，否则不变，其他方向类似
            this.action = Action.ACTION_KEY_UP.equals(this.action)
                    || Action.ACTION_KEY_DOWN.equals(this.action) ? Action.ACTION_KEY_LEFT
                    : this.action;
        } else if (Action.ACTION_KEY_RIGHT.equals(action)) {
            this.action = Action.ACTION_KEY_UP.equals(this.action)
                    || Action.ACTION_KEY_DOWN.equals(this.action) ? Action.ACTION_KEY_RIGHT
                    : this.action;
        } else if (Action.ACTION_KEY_UP.equals(action)) {
            this.action = Action.ACTION_KEY_LEFT.equals(this.action)
                    || Action.ACTION_KEY_RIGHT.equals(this.action) ? Action.ACTION_KEY_UP
                    : this.action;
        } else if (Action.ACTION_KEY_DOWN.equals(action)) {
            this.action = Action.ACTION_KEY_LEFT.equals(this.action)
                    || Action.ACTION_KEY_RIGHT.equals(this.action) ? Action.ACTION_KEY_DOWN
                    : this.action;
        }
    }

    /**
     * 
     * <P>
     * 描述: 修改游戏当前的状态 如果当前处在初始或暂停状态，则转为运行状态 如果当前出在运行状态，则转为暂停状态 如果当前为结束，就重新开一局
     * 
     * @author Zangrong.Solo 日期: Dec 18, 2012 5:29:47 PM
     */
    public void modifyGameState() {

        if (Game.GAME_STATE_INITIAL.equals(this.state)
                || Game.GAME_STATE_SUSPEND.equals(this.state)) {
            this.state = Game.GAME_STATE_RUNNING;
        } else if (Game.GAME_STATE_RUNNING.equals(this.state)) {
            this.state = Game.GAME_STATE_SUSPEND;
        } else if (Game.GAME_STATE_STOP.equals(this.state)) {
            initGame();
        }
    }

    public Bonus getBonus() {

        return this.bonus;
    }

    public JButton getField(int x, int y) {

        return matrix[x][y];
    }
    
    public String getState()
    {
        return this.state;
    }
    
    public void setState(String state)
    {
        this.state = state;
    }
}
